package main

import (
	"embed"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"os"

	"github.com/gin-gonic/gin"
	"gopkg.in/yaml.v2"

	"swift-webdrive/handlers"
	"swift-webdrive/services"
)

//go:embed templates/*
var templateFS embed.FS

//go:embed static/css/*
var staticFS embed.FS

type Config struct {
	Swift struct {
		AuthURL             string `yaml:"auth_url"`
		Username            string `yaml:"username"`
		Password            string `yaml:"password"`
		ProjectName         string `yaml:"project_name"`
		DomainName          string `yaml:"domain_name"`
		AuthMode            string `yaml:"auth_mode"`
		AppCredentialID     string `yaml:"app_credential_id"`
		AppCredentialSecret string `yaml:"app_credential_secret"`
		ContainerName       string `yaml:"container_name"`
	} `yaml:"swift"`

	FileRestrictions struct {
		MaxFileSize       string   `yaml:"max_file_size"`
		AllowedExtensions []string `yaml:"allowed_extensions"`
		BlockedExtensions []string `yaml:"blocked_extensions"`
	} `yaml:"file_restrictions"`

	App struct {
		Port           int    `yaml:"port"`
		Debug          bool   `yaml:"debug"`
		UploadPath     string `yaml:"upload_path"`
		SessionTimeout string `yaml:"session_timeout"`
	} `yaml:"app"`

	UI struct {
		CompanyName           string   `yaml:"company_name"`
		MaxFilesPerPage       int      `yaml:"max_files_per_page"`
		SupportedPreviewTypes []string `yaml:"supported_preview_types"`
	} `yaml:"ui"`
}

func main() {
	// 加载配置文件
	config, err := loadConfig("config.yaml")
	if err != nil {
		log.Fatalf("加载配置文件失败: %v", err)
	}

	// 根据认证方式创建Swift服务
	log.Println("🔌 验证Swift配置...")
	var swiftService *services.SwiftService

	if config.Swift.AuthMode == "application_credential" {
		if config.Swift.AppCredentialID == "" || config.Swift.AppCredentialSecret == "" {
			log.Fatalf("❌ 应用凭证认证配置不完整")
		}
		swiftService, err = services.NewSwiftServiceWithAppCredential(
			config.Swift.AuthURL,
			config.Swift.AppCredentialID,
			config.Swift.AppCredentialSecret,
		)
	} else {
		swiftService, err = services.NewSwiftService(
			config.Swift.AuthURL,
			config.Swift.Username,
			config.Swift.Password,
			config.Swift.ProjectName,
			config.Swift.DomainName,
		)
	}

	if err != nil {
		log.Fatalf("❌ Swift认证失败: %v", err)
	}

	// 验证容器访问权限
	_, err = swiftService.ListContainers()
	if err != nil {
		log.Fatalf("❌ Swift权限验证失败: %v", err)
	}

	log.Println("✅ Swift配置验证通过")

	// 设置Gin模式
	if !config.App.Debug {
		gin.SetMode(gin.ReleaseMode)
	}

	// 创建路由器
	router := gin.Default()

	// 加载嵌入的HTML模板
	tmpl := template.Must(template.New("").Funcs(template.FuncMap{
		"formatFileSize": services.FormatFileSize,
		"getFileIcon":    getFileIcon,
	}).ParseFS(templateFS, "templates/*"))
	router.SetHTMLTemplate(tmpl)

	// 嵌入的静态文件服务
	router.GET("/static/css/*filepath", func(c *gin.Context) {
		filepath := c.Param("filepath")
		c.FileFromFS("static/css"+filepath, http.FS(staticFS))
	})

	// 创建处理器
	configMap := configToMap(config)
	authHandler := handlers.NewAuthHandler(configMap)
	webdriveHandler := handlers.NewWebDriveHandler(swiftService, configMap)

	// 设置路由
	setupRoutes(router, authHandler, webdriveHandler)

	// 启动服务器
	port := fmt.Sprintf(":%d", config.App.Port)
	log.Printf("🚀 企业文档存储系统启动成功: :%s", port)
	log.Printf("📋 Swift用户信息:")
	log.Printf("   用户名: %s", config.Swift.Username)
	log.Printf("   认证方式: %s", config.Swift.AuthMode)
	log.Printf("   容器: %s", config.Swift.ContainerName)
	log.Printf("   项目: %s@%s", config.Swift.ProjectName, config.Swift.DomainName)

	if err := router.Run(port); err != nil {
		log.Fatalf("启动服务器失败: %v", err)
	}
}

func loadConfig(filename string) (*Config, error) {
	data, err := os.ReadFile(filename)
	if err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %v", err)
	}

	var config Config
	if err := yaml.Unmarshal(data, &config); err != nil {
		return nil, fmt.Errorf("解析配置文件失败: %v", err)
	}

	return &config, nil
}

func configToMap(config *Config) map[string]interface{} {
	return map[string]interface{}{
		"swift": map[string]interface{}{
			"auth_url":       config.Swift.AuthURL,
			"username":       config.Swift.Username,
			"password":       config.Swift.Password,
			"project_name":   config.Swift.ProjectName,
			"domain_name":    config.Swift.DomainName,
			"auth_mode":      config.Swift.AuthMode,
			"container_name": config.Swift.ContainerName,
		},
		"app": convertAppConfig(config.App),
	}
}

func convertUIConfig(ui struct {
	CompanyName           string   `yaml:"company_name"`
	MaxFilesPerPage       int      `yaml:"max_files_per_page"`
	SupportedPreviewTypes []string `yaml:"supported_preview_types"`
}) map[string]interface{} {
	return map[string]interface{}{
		"company_name":            ui.CompanyName,
		"max_files_per_page":      ui.MaxFilesPerPage,
		"supported_preview_types": convertStringSlice(ui.SupportedPreviewTypes),
	}
}

func convertFileRestrictions(restrictions struct {
	MaxFileSize       string   `yaml:"max_file_size"`
	AllowedExtensions []string `yaml:"allowed_extensions"`
	BlockedExtensions []string `yaml:"blocked_extensions"`
}) map[string]interface{} {
	return map[string]interface{}{
		"max_file_size":      restrictions.MaxFileSize,
		"allowed_extensions": convertStringSlice(restrictions.AllowedExtensions),
		"blocked_extensions": convertStringSlice(restrictions.BlockedExtensions),
	}
}

func convertAppConfig(app struct {
	Port           int    `yaml:"port"`
	Debug          bool   `yaml:"debug"`
	UploadPath     string `yaml:"upload_path"`
	SessionTimeout string `yaml:"session_timeout"`
}) map[string]interface{} {
	return map[string]interface{}{
		"port":            app.Port,
		"debug":           app.Debug,
		"upload_path":     app.UploadPath,
		"session_timeout": app.SessionTimeout,
	}
}

func convertStringSlice(slice []string) []interface{} {
	result := make([]interface{}, len(slice))
	for i, s := range slice {
		result[i] = s
	}
	return result
}

func setupRoutes(router *gin.Engine, authHandler *handlers.AuthHandler, webdriveHandler *handlers.WebDriveHandler) {
	// 首页和登录
	router.GET("/", authHandler.LoginPage)
	router.POST("/login", authHandler.Login)
	router.GET("/logout", authHandler.Logout)

	// 需要认证的路由组
	authorized := router.Group("/")
	authorized.Use(authHandler.RequireAuth)
	{
		// 网盘主页面
		authorized.GET("/webdrive", webdriveHandler.Dashboard)

		// 文件操作API
		authorized.POST("/upload",
			authHandler.RequirePermission("write"),
			webdriveHandler.UploadFile)

		authorized.GET("/download/:container/:object",
			webdriveHandler.DownloadFile)

		authorized.DELETE("/delete/:container/:object",
			authHandler.RequirePermission("delete"),
			webdriveHandler.DeleteFile)

		authorized.GET("/info/:container/:object",
			webdriveHandler.GetObjectInfo)
	}

	// 健康检查接口
	router.GET("/health", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"status":  "healthy",
			"service": "swift-webdrive",
		})
	})
}

func getFileIcon(filename string) string {
	ext := services.GetFileExtension(filename)
	icons := map[string]string{
		".pdf": "📄",
		".doc": "📝", ".docx": "📝",
		".xls": "📊", ".xlsx": "📊",
		".ppt": "📽️", ".pptx": "📽️",
		".txt": "📃",
		".jpg": "🖼️", ".jpeg": "🖼️", ".png": "🖼️",
		".zip": "📦",
	}

	if icon, exists := icons[ext]; exists {
		return icon
	}
	return "📄"
}
